(function() {
    var $ = require(L('$')), _ = require(L('_'));

    var RetailerStores = {};

    RetailerStores.detectNearestStore = function(callback) {
        if ($.is_debug()) {
            //currentLocationInfo = new LocationData(151, -33, null, 60, 0, null); //Australia
            //currentLocationInfo = new LocationData(10.7899, 106.699, null, 60, 0, null);//Vietnam
            //var currentLocationInfo = new LocationData(-33.87128, 151.20694, null, 60, 0, null);
            var currentLocationInfo = $.model('location')(-33.87128, 151.20694, null, 60, 0, null);

            callbackGetCurrentPosition(currentLocationInfo);
        } else if (Titanium.Geolocation.locationServicesEnabled) {
            //Ti.API.info('Retailer - showRetailerOptionsDialog - location service is enabled');
            $.gps().getCurrentPosition(callbackGetCurrentPosition);
        } else {
            //Ti.API.info('Retailer - showRetailerOptionsDialog - location service is disabled');
            callbackGetCurrentPosition(null);
        }

        function callbackGetCurrentPosition(locationData) {
            //var allRetailerStores = JSON.parse(Ti.App.Properties.getString("RetailerStores"));
            var allRetailerStores = RetailerStores.getRetailerStoresBelongToMyDesireRetailerIDs();
            if (locationData && allRetailerStores) {
                var nearestStore = RetailerStores.getNearestStore(locationData, allRetailerStores);
                if (callback)
                    callback(nearestStore);
            } else if (callback)
                callback(null);
        }

    };
    RetailerStores.detectRetailerStoreInRange = function(callback) {
        if ($.is_debug()) {
            //currentLocationInfo = new LocationData(151, -33, null, 60, 0, null); //Australia
            //currentLocationInfo = new LocationData(10.7899, 106.699, null, 60, 0, null); //Vietnam
            //currentLocationInfo = new LocationData(-33.87128, 151.20694, null, 60, 0, null);
            // var currentLocationInfo = $.model('location')(-33.87128, 151.20694, null, 60, 0, null);
            var currentLocationInfo = $.model('location')(45.54497, -73.799, null, 60, 0, null);

            callbackGetCurrentPosition(currentLocationInfo);
        } else if (Titanium.Geolocation.locationServicesEnabled) {
            //Ti.API.info('Retailer - showRetailerOptionsDialog - location service is enabled');
            $.gps().getCurrentPosition(callbackGetCurrentPosition);
        } else {
            //Ti.API.info('Retailer - showRetailerOptionsDialog - location service is disabled');
            callbackGetCurrentPosition(null);
        }

        function callbackGetCurrentPosition(locationData) {
            var allRetailerStores = RetailerStores.getRetailerStoresBelongToMyDesireRetailerIDs();
            //Ti.API.info('Retailer - callbackGetCurrentPosition - allRetailerStores: ' + JSON.stringify(allRetailerStores));

            if (locationData && allRetailerStores) {
                var retailerStores = RetailerStores.getRetailerStoresInRange(locationData, allRetailerStores);
                //Ti.API.info('Retailer - callbackGetCurrentPosition - retailerStores after detected range: ' + JSON.stringify(retailerStores));

                if (callback)
                    callback(retailerStores);

            } else if (callback)
                callback(null);
        }

    };
    RetailerStores.getRetailerStoresBelongToMyDesireRetailerIDs = function() {
        var result = new Array();
        var allRetailerStoresText = $.retailerStores();
        //Ti.API.info("getRetailerStoresBelongToMyDesireRetailerIDs - allRetailerStoresText: " + JSON.stringify(allRetailerStoresText));
        if (allRetailerStoresText) {
            var allRetailerStores = JSON.parse(allRetailerStoresText);
            var mydesireRetailerItemsText = $.mydesireRetailerItems();
            //Ti.API.info("getRetailerStoresBelongToMyDesireRetailerIDs - mydesireRetailerItemsText: " + JSON.stringify(mydesireRetailerItemsText));
            if (mydesireRetailerItemsText) {
                var mydesireRetailerItems = JSON.parse(mydesireRetailerItemsText);
                var mydesireRetailerIDs = new Array();
                if (mydesireRetailerItems) {
                    for (var i = 0; i < mydesireRetailerItems.length; i++) {
                        mydesireRetailerIDs.push(mydesireRetailerItems[i].retailerID);
                    }
                }

                for (var i = 0; i < allRetailerStores.length; i++) {
                    for (var j = 0; j < mydesireRetailerIDs.length; j++) {
                        if (allRetailerStores[i].RetailerID === mydesireRetailerIDs[j]) {
                            result.push(allRetailerStores[i]);
                        }
                    };
                };
            }
        }
        //Ti.API.info("getRetailerStoresBelongToMyDesireRetailerIDs - count: " + result.length + "; result: " + JSON.stringify(result));
        return result;
    };
    RetailerStores.getRetailerStoresInRange = function(currentLocation, retailerStores) {
        var storeCount = retailerStores.length;
        var dectectedStores = new Array();
        for (var i = 0; i < storeCount; i++) {
            var store = retailerStores[i];
            //Ti.API.info("getRetailerStoresInRange - index: " + i +  " - storeLat: " + store.Latitude +  " - storeLong: " + store.Longitude + " - currentLat :" + currentLocation.latitude+ " - currentLong :" + currentLocation.longitude);
            var distance = $.gps().calculateDistance(currentLocation.latitude, currentLocation.longitude, store.Latitude, store.Longitude, 'M');
            //Ti.API.info("getRetailerStoresInRange - index: " + i +  " - distance: " + distance + " - radius: " + store.Radius);

            if (distance < store.Radius) {
                store.exactedDistance = distance;
                dectectedStores.push(store);
            }
        }

        dectectedStores = _.sortBy(dectectedStores, function(item) {
            return item.exactedDistance;
        });
        return dectectedStores;
    };
    RetailerStores.getNearestStore = function(currentLocation, retailerStores) {
        var acceptedStores = RetailerStores.getRetailerStoresInRange(currentLocation, retailerStores);
        //Ti.API.info('getNearestStore - acceptedStores:' + JSON.stringify(acceptedStores));
        var storeCount = acceptedStores.length;

        if (storeCount >= 1) {
            return acceptedStores[0];
        } else {
            return null;
        }
    };
    RetailerStores.checkAndPushNotification = function(callback) {
        RetailerStores.detectRetailerStoreInRange(function(stores) {
            Ti.API.info("stores in range: " + JSON.stringify(stores));
            if (stores) {
                var _stores = new Array();

                var retailerIDs = new Array();
                var retailerStores = new Array();

                var mydesireRetailerItemsText = $.mydesireRetailerItems();
                var mydesireRetailerItems = null;
                if (mydesireRetailerItemsText)
                    mydesireRetailerItems = JSON.parse(mydesireRetailerItemsText);

                for (var i = 0; i < stores.length; i++) {
                    var currentRetailerID = stores[i].RetailerID;
                    var currentRetailerStoreItem = {
                        'RetailerStoreID' : stores[i].RetailerStoreID,
                        'Latitude' : stores[i].Latitude,
                        'Longitude' : stores[i].Longitude,
                        'ExactedDistance' : stores[i].exactedDistance,
                    };

                    // var currentRetailerStoreID = stores[i].RetailerStoreID;

                    var retailerIDIndex = -1;
                    for (var j = 0; j < retailerIDs.length; j++) {
                        if (currentRetailerID === retailerIDs[j]) {
                            retailerIDIndex = j;
                            break;
                        }
                    }
                    if (retailerIDIndex < 0) {
                        retailerIDs.push(currentRetailerID);
                        retailerIDIndex = retailerIDs.length - 1;
                    }

                    if (currentRetailerStoreItem != null && currentRetailerStoreItem != undefined) {
                        var listRetailerStores = retailerStores[retailerIDIndex];
                        if (listRetailerStores) {
                            listRetailerStores.push(currentRetailerStoreItem);
                            retailerStores[retailerIDIndex] = listRetailerStores;
                        } else {
                            listRetailerStores = new Array();
                            listRetailerStores.push(currentRetailerStoreItem);
                            retailerStores.push(listRetailerStores);
                        }
                    }
                };

                //Ti.API.info("detectRetailerStoreInRange - mydesireRetailerItems: " + JSON.stringify(mydesireRetailerItems));
                //Ti.API.info("detectRetailerStoreInRange - retailerIDs: " + JSON.stringify(retailerIDs));
                var locationList = new Array();
                for (var i = 0; i < retailerIDs.length; i++) {
                    var item = {
                        'RetailerID' : retailerIDs[i],
                        'RetailerStores' : retailerStores[i],
                        'ProductVariantIDs' : null
                    };

                    if (mydesireRetailerItems) {
                        for (var j = 0; j < mydesireRetailerItems.length; j++) {
                            var mydesireRetailerItem = mydesireRetailerItems[j];
                            if (currentRetailerID === mydesireRetailerItem.retailerID) {
                                item.ProductVariantIDs = mydesireRetailerItem.productVariantIDs;
                                break;
                            }
                        }
                    }
                    locationList.push(item);
                }
                //Ti.API.info("request list in range: " + JSON.stringify(locationList));
                if (locationList && locationList.length > 0) {
                    $.webservice().nearLocationsDetected(locationList, callback);
                }
            }
        });
    };
    RetailerStores.init = function() {

        var timeOffset = $.is_debug() ? 3000 : parseFloat($.detectNearestLocationTimming());
        if (timeOffset > 0) {
            var s = setInterval(function() {
                //Ti.API.info('detect in range');
                RetailerStores.checkAndPushNotification(function(e) {
                    Ti.API.info('detected a store in range, push notification to device: ok');
                });
            }, timeOffset);
        } else {
            RetailerStores.checkAndPushNotification(function(e) {
                Ti.API.info('detected a store in range, push notification to device: ok');
            });
        }
    };

    module.exports = RetailerStores;
})();
